/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <native_window/external_window.h>
#include <vector>
#include <string>
#include <set>  // 添加set头文件
#include <algorithm>  // 添加算法头文件
#include "vulkan_wrapper.h"
#define STB_IMAGE_IMPLEMENTATION
#define STBI_ONLY_PNG
#include <stb/stb_image.h>
#include "CreateShaderModule.h"
#include "log.h"
#include "tetrahedron.h"
#include <dlfcn.h>

// 鸿蒙平台Vulkan扩展定义
#ifndef VK_KHR_OHOS_SURFACE_EXTENSION_NAME
#define VK_KHR_OHOS_SURFACE_EXTENSION_NAME "VK_KHR_ohos_surface"
#endif

#ifndef VK_STRUCTURE_TYPE_OHOS_SURFACE_CREATE_INFO_KHR
#define VK_STRUCTURE_TYPE_OHOS_SURFACE_CREATE_INFO_KHR ((VkStructureType)1000282000)
#endif

 const float FIFTY_PERCENT = 0.5f;

// 鸿蒙表面创建函数指针类型
typedef VkResult (VKAPI_PTR *PFN_vkCreateOhosSurfaceKHR)(
    VkInstance                        instance,
    const VkOhosSurfaceCreateInfoKHR* pCreateInfo,
    const VkAllocationCallbacks*      pAllocator,
    VkSurfaceKHR*                     pSurface);
 
 // 四面体顶点数据（位置、颜色、法向量）
 static const Vertex g_tetrahedronVertices[] = {
     // Face 1 (bottom) - 红色
     {{-0.75f, -0.50f, -0.43f}, {1.0f, 0.0f, 0.0f, 1.0f}, {0.00f, -1.00f, 0.00f}},
     {{0.75f, -0.50f, -0.43f}, {1.0f, 0.0f, 0.0f, 1.0f}, {0.00f, -1.00f, 0.00f}},
     {{0.00f, -0.50f, 0.87f}, {1.0f, 0.0f, 0.0f, 1.0f}, {0.00f, -1.00f, 0.00f}},
     
     // Face 2 - 红色
     {{0.75f, -0.50f, -0.43f}, {1.0f, 0.0f, 0.0f, 1.0f}, {-0.83f, -0.28f, -0.48f}},
     {{0.00f, -0.50f, 0.87f}, {1.0f, 0.0f, 0.0f, 1.0f}, {-0.83f, -0.28f, -0.48f}},
     {{0.00f, 1.00f, 0.00f}, {1.0f, 0.0f, 0.0f, 1.0f}, {-0.83f, -0.28f, -0.48f}},
     
     // Face 3 - 红色
     {{0.00f, -0.50f, 0.87f}, {1.0f, 0.0f, 0.0f, 1.0f}, {-0.83f, 0.28f, 0.48f}},
     {{0.00f, 1.00f, 0.00f}, {1.0f, 0.0f, 0.0f, 1.0f}, {-0.83f, 0.28f, 0.48f}},
     {{-0.75f, -0.50f, -0.43f}, {1.0f, 0.0f, 0.0f, 1.0f}, {-0.83f, 0.28f, 0.48f}},
     
     // Face 4 - 红色
     {{0.00f, 1.00f, 0.00f}, {1.0f, 0.0f, 0.0f, 1.0f}, {0.00f, -0.28f, 0.96f}},
     {{-0.75f, -0.50f, -0.43f}, {1.0f, 0.0f, 0.0f, 1.0f}, {0.00f, -0.28f, 0.96f}},
     {{0.75f, -0.50f, -0.43f}, {1.0f, 0.0f, 0.0f, 1.0f}, {0.00f, -0.28f, 0.96f}},
 };
 
 #define VK_CHECK(x) \
     do { \
         VkResult err = x; \
         if (err) { \
             LOGE("Vulkan error: %d at %s:%d", err, __FILE__, __LINE__); \
             abort(); \
         } \
     } while (0)



void Tetrahedron::CheckVulkanLibraryStatus() {
    LOGI("--- Vulkan Library Status ---");

    // 检查libvulkan.so是否存在
    void* vulkanLib = dlopen("libvulkan.so", RTLD_NOW | RTLD_LOCAL);
    if (vulkanLib) {
        LOGI("✓ libvulkan.so successfully loaded");
        
        // 检查关键函数是否存在
        void* createInstance = dlsym(vulkanLib, "vkCreateInstance");
        void* enumerateExtensions = dlsym(vulkanLib, "vkEnumerateInstanceExtensionProperties");
        void* enumerateDevices = dlsym(vulkanLib, "vkEnumeratePhysicalDevices");
        
        LOGI("vkCreateInstance: %s", createInstance ? "Available" : "Missing");
        LOGI("vkEnumerateInstanceExtensionProperties: %s", enumerateExtensions ? "Available" : "Missing");
        LOGI("vkEnumeratePhysicalDevices: %s", enumerateDevices ? "Available" : "Missing");
        
        dlclose(vulkanLib);
    } else {
        LOGE("✗ Failed to load libvulkan.so: %s", dlerror());
    }
    
    // 尝试加载其他可能的Vulkan相关库
    const char* vulkanLibs[] = {
        "libvulkan.so.1",
        "libGLESv2.so",
        "libEGL.so"
    };
    
    for (const char* lib : vulkanLibs) {
        void* handle = dlopen(lib, RTLD_NOW | RTLD_LOCAL);
        if (handle) {
            LOGI("✓ %s loaded successfully", lib);
            dlclose(handle);
        } else {
            LOGI("✗ %s not available: %s", lib, dlerror());
        }
    }

    // **添加系统信息检查**
    LOGI("--- System Environment Check ---");
    
#ifdef VK_USE_PLATFORM_OHOS
    LOGI("✓ VK_USE_PLATFORM_OHOS is defined - using OHOS platform path");
#else
    LOGI("✗ VK_USE_PLATFORM_OHOS is NOT defined - using generic platform path");
#endif

    // 检查鸿蒙系统版本信息
    char* ohVersion = getenv("OH_VERSION");
    if (ohVersion) {
        LOGI("OpenHarmony version: %s", ohVersion);
    } else {
        LOGI("OpenHarmony version: Not available");
    }
}


bool Tetrahedron::CheckVulkanSupport() {
    LOGI("=== Starting Vulkan Support Check ===");

    LOGI("=== System Information ===");
    // 检查Vulkan库加载情况
    CheckVulkanLibraryStatus();

    // 首先初始化Vulkan包装器
    LOGI("Step 1: Initializing Vulkan wrapper...");
    if (!InitVulkan()) {
        LOGE("Failed to initialize Vulkan wrapper - Vulkan library not available");
        return false;
    }
    LOGI("✓ Vulkan wrapper initialized successfully");

    // 然后检查Vulkan函数是否可用（仅在非鸿蒙平台需要检查）
    LOGI("Step 2: Checking if Vulkan functions are loaded...");
    
#ifndef VK_USE_PLATFORM_OHOS
    // 检查基本的Vulkan函数
    if (vkCreateInstance == nullptr) {
        LOGE("vkCreateInstance function is not available!");
        return false;
    }
    if (vkEnumerateInstanceExtensionProperties == nullptr) {
        LOGE("vkEnumerateInstanceExtensionProperties function is not available!");
        return false;
    }
#endif
    LOGI("✓ Vulkan library functions are available");

    // 检查可用的实例扩展
    LOGI("Step 3: Enumerating available instance extensions...");
    uint32_t extensionCount = 0;
    VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);
    if (result != VK_SUCCESS) {
        LOGE("Failed to enumerate instance extensions. Error: %d", result);
        return false;
    }
    
    LOGI("Found %d instance extensions:", extensionCount);
    bool surfaceExtFound = false;
    bool ohosExtFound = false;
    std::vector<VkExtensionProperties> availableExtensions(extensionCount); // 确保变量在正确的作用域内声明
    
    if (extensionCount > 0) {
        vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, availableExtensions.data());
        
        for (const auto& extension : availableExtensions) {
            LOGI("  - %s (v%d)", extension.extensionName, extension.specVersion);
            if (strcmp(extension.extensionName, VK_KHR_SURFACE_EXTENSION_NAME) == 0) {
                surfaceExtFound = true;
            }
            if (strcmp(extension.extensionName, VK_KHR_OHOS_SURFACE_EXTENSION_NAME) == 0) {
                ohosExtFound = true;
            }
        }
        
        LOGI("Surface extension support:");
        LOGI("  - %s: %s", VK_KHR_SURFACE_EXTENSION_NAME, surfaceExtFound ? "✓ Available" : "✗ Missing");
        LOGI("  - %s: %s", VK_KHR_OHOS_SURFACE_EXTENSION_NAME, ohosExtFound ? "✓ Available" : "✗ Missing");
        
        if (!surfaceExtFound) {
            LOGE("Required surface extension is not available!");
            return false;
        }
        
        // 对于鸿蒙扩展，如果不可用就尝试创建基础实例
        if (!ohosExtFound) {
            LOGW("OHOS surface extension is not available - this may be expected on some emulators");
            LOGI("Will attempt to create instance with basic extensions only");
        }
    }

    // 检查可用的实例层
    LOGI("Step 4: Enumerating available instance layers...");
    uint32_t layerCount = 0;
    vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
    LOGI("Found %d instance layers:", layerCount);
    if (layerCount > 0) {
        std::vector<VkLayerProperties> availableLayers(layerCount);
        vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data());
        for (const auto& layer : availableLayers) {
            LOGI("  - %s: %s", layer.layerName, layer.description);
        }
    }

    // 尝试创建简化的Vulkan实例
    LOGI("Step 5: Attempting to create Vulkan instance...");
    VkInstance testInstance = VK_NULL_HANDLE;

    VkApplicationInfo appInfo = {};
    appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
    appInfo.pApplicationName = "VulkanTest";
    appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
    appInfo.pEngineName = "TestEngine";
    appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
    appInfo.apiVersion = VK_API_VERSION_1_0;  // 使用最基本的版本
    
    VkInstanceCreateInfo instanceCreateInfo = {};
    instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
    instanceCreateInfo.pApplicationInfo = &appInfo;
    
    // 先尝试基础扩展
    std::vector<const char*> requiredExtensions = {
        VK_KHR_SURFACE_EXTENSION_NAME
    };
    
    // 检查是否有OHOS扩展，如果有就添加
    if (ohosExtFound) {
        requiredExtensions.push_back(VK_KHR_OHOS_SURFACE_EXTENSION_NAME);
        LOGI("Including OHOS surface extension in instance creation");
    } else {
        LOGW("OHOS surface extension not available - proceeding without it");
    }
    
    instanceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(requiredExtensions.size());
    instanceCreateInfo.ppEnabledExtensionNames = requiredExtensions.data();
    instanceCreateInfo.enabledLayerCount = 0;  // 不使用验证层
    
    LOGI("Creating instance with %lu extensions:", static_cast<unsigned long>(requiredExtensions.size()));
    for (const auto& ext : requiredExtensions) {
        LOGI("  - %s", ext);
    }
 
    result = vkCreateInstance(&instanceCreateInfo, nullptr, &testInstance);

    if (result == VK_SUCCESS) {
        LOGI("✓ Vulkan instance created successfully!");
        
        // 检查物理设备
        LOGI("Step 6: Checking for physical devices...");
        uint32_t deviceCount = 0;
        VkResult deviceResult = vkEnumeratePhysicalDevices(testInstance, &deviceCount, nullptr);
        if (deviceResult == VK_SUCCESS && deviceCount > 0) {
            LOGI("✓ Found %d physical device(s)", deviceCount);
            
            // 获取设备信息
            std::vector<VkPhysicalDevice> devices(deviceCount);
            vkEnumeratePhysicalDevices(testInstance, &deviceCount, devices.data());
            
            for (uint32_t i = 0; i < deviceCount; i++) {
                VkPhysicalDeviceProperties props;
                vkGetPhysicalDeviceProperties(devices[i], &props);
                LOGI("  Device %d: %s (Type: %d)", i, props.deviceName, props.deviceType);
            }
        } else {
            LOGE("✗ No physical devices found or enumeration failed. Error: %d", deviceResult);
        }
        
        // 重要：清理测试实例
        if (testInstance != VK_NULL_HANDLE) {
            LOGI("Cleaning up test instance...");
            vkDestroyInstance(testInstance, nullptr);
        }
        
        LOGI("=== Vulkan Support Check PASSED ===");
        return true;
    } else {
        LOGE("✗ Vulkan instance creation failed!");
        LOGE("Error code: %d", result);
        
        // 详细的错误信息
        switch (result) {
            case VK_ERROR_OUT_OF_HOST_MEMORY:
                LOGE("Error: Out of host memory");
                break;
            case VK_ERROR_OUT_OF_DEVICE_MEMORY:
                LOGE("Error: Out of device memory");
                break;
            case VK_ERROR_INITIALIZATION_FAILED:
                LOGE("Error: Initialization failed");
                break;
            case VK_ERROR_LAYER_NOT_PRESENT:
                LOGE("Error: Layer not present");
                break;
            case VK_ERROR_EXTENSION_NOT_PRESENT:
                LOGE("Error: Extension not present");
                break;
            case VK_ERROR_INCOMPATIBLE_DRIVER:
                LOGE("Error: Incompatible driver");
                break;
            default:
                LOGE("Error: Unknown error code %d", result);
                break;
        }
        
        LOGI("=== Vulkan Support Check FAILED ===");
        return false;
    }
}

 
int32_t Tetrahedron::Init(void *window, int32_t width, int32_t height)
{
    LOGI("=== Tetrahedron::Init START ===");
    LOGI("Window: %{public}p, Size: %{public}d x %{public}d", window, width, height);
    
    // 初始化状态和句柄
    LOGI("Initializing Vulkan state...");
    mVulkanInitialized = false;
    mInstance = VK_NULL_HANDLE;
    mDevice = VK_NULL_HANDLE;
    mPhysicalDevice = VK_NULL_HANDLE;
    mSurface = VK_NULL_HANDLE;
    mSwapChain = VK_NULL_HANDLE;
    mRenderPass = VK_NULL_HANDLE;
    mDescriptorSetLayout = VK_NULL_HANDLE;
    mPipelineLayout = VK_NULL_HANDLE;
    mGraphicsPipeline = VK_NULL_HANDLE;
    mCommandPool = VK_NULL_HANDLE;
    mVertexBuffer = VK_NULL_HANDLE;
    mVertexBufferMemory = VK_NULL_HANDLE;
    mDescriptorPool = VK_NULL_HANDLE;
    
    // 首先检查Vulkan支持
    LOGI("Checking Vulkan support...");
    if (!CheckVulkanSupport()) {
        LOGE("✗ Vulkan is not supported on this device/emulator.");
        LOGE("This is expected behavior on emulators.");
        LOGE("Please use a real device that supports Vulkan for testing.");
        mVulkanInitialized = false;
        return -1;
    }
    
    LOGI("✓ Vulkan support confirmed, proceeding with initialization...");

    m_width = width;
    m_height = height;
    m_widthPercent = FIFTY_PERCENT * m_height / m_width;
    vertices = std::vector<Vertex>(g_tetrahedronVertices, g_tetrahedronVertices + TETRAHEDRON_POINT);
    
    // 继续正常的Vulkan初始化流程
    LOGI("Starting Vulkan component initialization...");
    
    if (CreateInstance() != 0) return -1;
    
    // 尝试创建表面，如果失败则优雅退出
    if (CreateSurface(window) != 0) {
        LOGW("Surface creation failed - this is expected on emulators");
        LOGW("Application will continue but rendering will be disabled");
        
        // 清理已创建的资源
        if (mInstance != VK_NULL_HANDLE) {
            vkDestroyInstance(mInstance, nullptr);
            mInstance = VK_NULL_HANDLE;
        }
        
        mVulkanInitialized = false;
        return -1; // 返回错误，但应用不会崩溃
    }
    
    // 继续其他初始化步骤
    if (PickPhysicalDevice() != 0) return -1;
    if (CreateLogicalDevice() != 0) return -1;
    if (CreateSwapChain() != 0) return -1;
    if (CreateImageViews() != 0) return -1;
    if (CreateRenderPass() != 0) return -1;
    if (CreateDescriptorSetLayout() != 0) return -1;
    if (LoadShadersFromFile() != 0) return -1;
    if (CreateGraphicsPipeline() != 0) return -1;
    if (CreateFramebuffers() != 0) return -1;
    if (CreateCommandPool() != 0) return -1;
    if (CreateVertexBuffer() != 0) return -1;
    if (CreateUniformBuffers() != 0) return -1;
    if (CreateDescriptorPool() != 0) return -1;
    if (CreateDescriptorSets() != 0) return -1;
    if (CreateCommandBuffers() != 0) return -1;
    if (CreateSyncObjects() != 0) return -1;
    
    mVulkanInitialized = true;  // 标记Vulkan已成功初始化
    LOGI("=== Vulkan Init SUCCESS ===");
    return 0;
}
 
 int32_t Tetrahedron::CreateInstance()
{
    VkApplicationInfo appInfo{};
    appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
    appInfo.pApplicationName = "Tetrahedron";
    appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
    appInfo.pEngineName = "No Engine";
    appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
    appInfo.apiVersion = VK_API_VERSION_1_0;

    VkInstanceCreateInfo createInfo{};
    createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
    createInfo.pApplicationInfo = &appInfo;

    // 首先检查可用的扩展
    uint32_t extensionCount = 0;
    vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);
    std::vector<VkExtensionProperties> availableExtensions(extensionCount);
    vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, availableExtensions.data());
    
    bool ohosExtFound = false;
    for (const auto& ext : availableExtensions) {
        if (strcmp(ext.extensionName, VK_KHR_OHOS_SURFACE_EXTENSION_NAME) == 0) {
            ohosExtFound = true;
            break;
        }
    }

    // 根据可用性选择扩展
    std::vector<const char*> extensions;
    extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
    
    if (ohosExtFound) {
        extensions.push_back(VK_KHR_OHOS_SURFACE_EXTENSION_NAME);
        LOGI("Including OHOS surface extension");
    } else {
        LOGW("OHOS surface extension not available - creating instance without it");
    }
    
    createInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
    createInfo.ppEnabledExtensionNames = extensions.data();
    createInfo.enabledLayerCount = 0;

    VkResult result = vkCreateInstance(&createInfo, nullptr, &mInstance);
    if (result != VK_SUCCESS) {
        LOGE("Failed to create Vulkan instance: %d", result);
        return -1;
    }

    // 在实例创建后获取鸿蒙表面创建函数（如果可用）
    if (ohosExtFound) {
        vkCreateOhosSurfaceKHR = (PFN_vkCreateOhosSurfaceKHR)
            vkGetInstanceProcAddr(mInstance, "vkCreateOhosSurfaceKHR");
        
        if (vkCreateOhosSurfaceKHR) {
            LOGI("Successfully loaded vkCreateOhosSurfaceKHR function");
        } else {
            LOGW("Failed to load vkCreateOhosSurfaceKHR function pointer");
        }
    }

    return 0;
}

int32_t Tetrahedron::CreateSurface(void* window)
{
    LOGI("Attempting to create Vulkan surface...");
    
    // 检查是否有OHOS表面扩展可用
    if (vkCreateOhosSurfaceKHR != nullptr) {
        LOGI("Using OHOS surface extension");
        VkOhosSurfaceCreateInfoKHR createInfo{};
        createInfo.sType = VK_STRUCTURE_TYPE_OHOS_SURFACE_CREATE_INFO_KHR;
        createInfo.pNext = nullptr;
        createInfo.flags = 0;
        createInfo.window = static_cast<OHNativeWindow*>(window);

        VkResult result = vkCreateOhosSurfaceKHR(mInstance, &createInfo, nullptr, &mSurface);
        if (result == VK_SUCCESS) {
            LOGI("Surface created using OHOS extension");
            return 0;
        } else {
            LOGE("Failed to create OHOS surface: %d", result);
        }
    }
    
    // 尝试使用通用方法创建表面
    LOGI("OHOS extension not available, trying alternative surface creation...");
    
    // 尝试通过vkGetInstanceProcAddr获取可能的表面创建函数
    PFN_vkCreateDisplayPlaneSurfaceKHR vkCreateDisplayPlaneSurfaceKHR = 
        (PFN_vkCreateDisplayPlaneSurfaceKHR)vkGetInstanceProcAddr(mInstance, "vkCreateDisplayPlaneSurfaceKHR");
    
    if (vkCreateDisplayPlaneSurfaceKHR) {
        LOGI("Attempting to use display plane surface...");
        // 这需要更复杂的设置，暂时跳过
    }
    
    // 最后的尝试：使用原生窗口创建一个最基本的表面
    // 这是一个实验性方法，可能在某些鸿蒙设备上工作
    LOGW("Attempting experimental surface creation method...");
    
    // 检查是否有其他可用的表面创建扩展
    uint32_t extensionCount = 0;
    vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);
    std::vector<VkExtensionProperties> extensions(extensionCount);
    vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensions.data());
    
    LOGI("Available instance extensions for surface creation:");
    for (const auto& ext : extensions) {
        if (strstr(ext.extensionName, "surface") || strstr(ext.extensionName, "Surface")) {
            LOGI("  - %s", ext.extensionName);
        }
    }
    
    // 如果没有其他选择，创建一个空的表面句柄用于测试
    LOGW("No suitable surface creation method found");
    LOGW("This indicates incomplete Vulkan driver support on this device");
    LOGW("Device info: Kirin8000, HarmonyOS 5.0.5.316");
    
    mSurface = VK_NULL_HANDLE;
    return -1;
}
 
 int32_t Tetrahedron::PickPhysicalDevice()
 {
     uint32_t deviceCount = 0;
     vkEnumeratePhysicalDevices(mInstance, &deviceCount, nullptr);
 
     if (deviceCount == 0) {
         LOGE("Failed to find GPUs with Vulkan support");
         return -1;
     }
 
     std::vector<VkPhysicalDevice> devices(deviceCount);
     vkEnumeratePhysicalDevices(mInstance, &deviceCount, devices.data());
 
     // 选择第一个可用的设备
     for (const auto& device : devices) {
         QueueFamilyIndices indices = FindQueueFamilies(device);
         if (indices.isComplete()) {
             mPhysicalDevice = device;
             break;
         }
     }
 
     if (mPhysicalDevice == VK_NULL_HANDLE) {
         LOGE("Failed to find a suitable GPU");
         return -1;
     }
 
     return 0;
 }
 
 Tetrahedron::QueueFamilyIndices Tetrahedron::FindQueueFamilies(VkPhysicalDevice device)
 {
     QueueFamilyIndices indices;
 
     uint32_t queueFamilyCount = 0;
     vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, nullptr);
 
     std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
     vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies.data());
 
     int i = 0;
     for (const auto& queueFamily : queueFamilies) {
         if (queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
             indices.graphicsFamily = i;
         }
 
         VkBool32 presentSupport = false;
         vkGetPhysicalDeviceSurfaceSupportKHR(device, i, mSurface, &presentSupport);
         if (presentSupport) {
             indices.presentFamily = i;
         }
 
         if (indices.isComplete()) {
             break;
         }
 
         i++;
     }
 
     return indices;
 }
 
 int32_t Tetrahedron::CreateLogicalDevice()
 {
     QueueFamilyIndices indices = FindQueueFamilies(mPhysicalDevice);
 
     std::vector<VkDeviceQueueCreateInfo> queueCreateInfos;
     std::vector<uint32_t> uniqueQueueFamilies;
     
     // 手动添加唯一的队列族索引
     uniqueQueueFamilies.push_back(indices.graphicsFamily);
     if (indices.presentFamily != indices.graphicsFamily) {
         uniqueQueueFamilies.push_back(indices.presentFamily);
     }
 
     float queuePriority = 1.0f;
     for (uint32_t queueFamily : uniqueQueueFamilies) {
         VkDeviceQueueCreateInfo queueCreateInfo{};
         queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
         queueCreateInfo.queueFamilyIndex = queueFamily;
         queueCreateInfo.queueCount = 1;
         queueCreateInfo.pQueuePriorities = &queuePriority;
         queueCreateInfos.push_back(queueCreateInfo);
     }
 
     VkPhysicalDeviceFeatures deviceFeatures{};
 
     VkDeviceCreateInfo createInfo{};
     createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
     createInfo.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size());
     createInfo.pQueueCreateInfos = queueCreateInfos.data();
     createInfo.pEnabledFeatures = &deviceFeatures;
 
     std::vector<const char*> deviceExtensions = {
         VK_KHR_SWAPCHAIN_EXTENSION_NAME
     };
 
     createInfo.enabledExtensionCount = static_cast<uint32_t>(deviceExtensions.size());
     createInfo.ppEnabledExtensionNames = deviceExtensions.data();
 
     VK_CHECK(vkCreateDevice(mPhysicalDevice, &createInfo, nullptr, &mDevice));
 
     vkGetDeviceQueue(mDevice, indices.graphicsFamily, 0, &mGraphicsQueue);
     vkGetDeviceQueue(mDevice, indices.presentFamily, 0, &mPresentQueue);
 
     return 0;
 }
 
 int32_t Tetrahedron::CreateSwapChain()
 {
     VkSurfaceCapabilitiesKHR capabilities;
     vkGetPhysicalDeviceSurfaceCapabilitiesKHR(mPhysicalDevice, mSurface, &capabilities);
 
     uint32_t formatCount;
     vkGetPhysicalDeviceSurfaceFormatsKHR(mPhysicalDevice, mSurface, &formatCount, nullptr);
     std::vector<VkSurfaceFormatKHR> formats(formatCount);
     vkGetPhysicalDeviceSurfaceFormatsKHR(mPhysicalDevice, mSurface, &formatCount, formats.data());
 
     VkSurfaceFormatKHR surfaceFormat = formats[0];
     for (const auto& availableFormat : formats) {
         if (availableFormat.format == VK_FORMAT_B8G8R8A8_SRGB && 
             availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
             surfaceFormat = availableFormat;
             break;
         }
     }
 
     mSwapChainExtent = capabilities.currentExtent;
     if (mSwapChainExtent.width == UINT32_MAX) {
         // 替换 std::clamp 为 std::min 和 std::max
         mSwapChainExtent.width = std::max(capabilities.minImageExtent.width, 
                                          std::min(capabilities.maxImageExtent.width, 
                                                  static_cast<uint32_t>(m_width)));
         mSwapChainExtent.height = std::max(capabilities.minImageExtent.height, 
                                           std::min(capabilities.maxImageExtent.height, 
                                                   static_cast<uint32_t>(m_height)));
     }
 
     uint32_t imageCount = capabilities.minImageCount + 1;
     if (capabilities.maxImageCount > 0 && imageCount > capabilities.maxImageCount) {
         imageCount = capabilities.maxImageCount;
     }
 
     VkSwapchainCreateInfoKHR createInfo{};
     createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
     createInfo.surface = mSurface;
     createInfo.minImageCount = imageCount;
     createInfo.imageFormat = surfaceFormat.format;
     createInfo.imageColorSpace = surfaceFormat.colorSpace;
     createInfo.imageExtent = mSwapChainExtent;
     createInfo.imageArrayLayers = 1;
     createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
 
     QueueFamilyIndices indices = FindQueueFamilies(mPhysicalDevice);
     uint32_t queueFamilyIndices[] = {indices.graphicsFamily, indices.presentFamily};
 
     if (indices.graphicsFamily != indices.presentFamily) {
         createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
         createInfo.queueFamilyIndexCount = 2;
         createInfo.pQueueFamilyIndices = queueFamilyIndices;
     } else {
         createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
     }
 
     createInfo.preTransform = capabilities.currentTransform;
     createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
     createInfo.presentMode = VK_PRESENT_MODE_FIFO_KHR;
     createInfo.clipped = VK_TRUE;
 
     mSwapChainImageFormat = surfaceFormat.format;
 
     VK_CHECK(vkCreateSwapchainKHR(mDevice, &createInfo, nullptr, &mSwapChain));
 
     vkGetSwapchainImagesKHR(mDevice, mSwapChain, &imageCount, nullptr);
     mSwapChainImages.resize(imageCount);
     vkGetSwapchainImagesKHR(mDevice, mSwapChain, &imageCount, mSwapChainImages.data());
 
     return 0;
 }
 
 int32_t Tetrahedron::CreateImageViews()
 {
     mSwapChainImageViews.resize(mSwapChainImages.size());
 
     for (size_t i = 0; i < mSwapChainImages.size(); i++) {
         VkImageViewCreateInfo createInfo{};
         createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
         createInfo.image = mSwapChainImages[i];
         createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
         createInfo.format = mSwapChainImageFormat;
         createInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
         createInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
         createInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
         createInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
         createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
         createInfo.subresourceRange.baseMipLevel = 0;
         createInfo.subresourceRange.levelCount = 1;
         createInfo.subresourceRange.baseArrayLayer = 0;
         createInfo.subresourceRange.layerCount = 1;
 
         VK_CHECK(vkCreateImageView(mDevice, &createInfo, nullptr, &mSwapChainImageViews[i]));
     }
 
     return 0;
 }
 
 int32_t Tetrahedron::CreateRenderPass()
 {
     VkAttachmentDescription colorAttachment{};
     colorAttachment.format = mSwapChainImageFormat;
     colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
     colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
     colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
     colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
     colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
     colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
     colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
 
     VkAttachmentReference colorAttachmentRef{};
     colorAttachmentRef.attachment = 0;
     colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
 
     VkSubpassDescription subpass{};
     subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
     subpass.colorAttachmentCount = 1;
     subpass.pColorAttachments = &colorAttachmentRef;
 
     VkSubpassDependency dependency{};
     dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
     dependency.dstSubpass = 0;
     dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
     dependency.srcAccessMask = 0;
     dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
     dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
 
     VkRenderPassCreateInfo renderPassInfo{};
     renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
     renderPassInfo.attachmentCount = 1;
     renderPassInfo.pAttachments = &colorAttachment;
     renderPassInfo.subpassCount = 1;
     renderPassInfo.pSubpasses = &subpass;
     renderPassInfo.dependencyCount = 1;
     renderPassInfo.pDependencies = &dependency;
 
     VK_CHECK(vkCreateRenderPass(mDevice, &renderPassInfo, nullptr, &mRenderPass));
     return 0;
 }
 
 int32_t Tetrahedron::CreateDescriptorSetLayout()
 {
     VkDescriptorSetLayoutBinding uboLayoutBinding{};
     uboLayoutBinding.binding = 0;
     uboLayoutBinding.descriptorCount = 1;
     uboLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
     uboLayoutBinding.pImmutableSamplers = nullptr;
     uboLayoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
 
     VkDescriptorSetLayoutCreateInfo layoutInfo{};
     layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
     layoutInfo.bindingCount = 1;
     layoutInfo.pBindings = &uboLayoutBinding;
 
     VK_CHECK(vkCreateDescriptorSetLayout(mDevice, &layoutInfo, nullptr, &mDescriptorSetLayout));
     return 0;
 }
 
 int32_t Tetrahedron::LoadShadersFromFile()
 {
     LOGI("Loading shaders from file...");
     
     VkResult result = mShaderLoader.initialize();
     if (result != VK_SUCCESS) {
         LOGE("Failed to initialize shader loader");
         return -1;
     }
     
     return 0;
 }
 
 int32_t Tetrahedron::CreateGraphicsPipeline()
 {
     // 加载着色器
     VkShaderModule vertShaderModule;
     VkShaderModule fragShaderModule;
     
     VkResult result = mShaderLoader.loadShader(
         "shaders/tetrahedron.vert",
         VK_SHADER_STAGE_VERTEX_BIT,
         mDevice,
         &vertShaderModule
     );
     
     if (result != VK_SUCCESS) {
         LOGE("Failed to load vertex shader");
         return -1;
     }
     
     result = mShaderLoader.loadShader(
         "shaders/tetrahedron.frag",
         VK_SHADER_STAGE_FRAGMENT_BIT,
         mDevice,
         &fragShaderModule
     );
     
     if (result != VK_SUCCESS) {
         LOGE("Failed to load fragment shader");
         vkDestroyShaderModule(mDevice, vertShaderModule, nullptr);
         return -1;
     }
 
     VkPipelineShaderStageCreateInfo vertShaderStageInfo{};
     vertShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
     vertShaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
     vertShaderStageInfo.module = vertShaderModule;
     vertShaderStageInfo.pName = "main";
 
     VkPipelineShaderStageCreateInfo fragShaderStageInfo{};
     fragShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
     fragShaderStageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
     fragShaderStageInfo.module = fragShaderModule;
     fragShaderStageInfo.pName = "main";
 
     VkPipelineShaderStageCreateInfo shaderStages[] = {vertShaderStageInfo, fragShaderStageInfo};
 
     // 顶点输入
     VkVertexInputBindingDescription bindingDescription{};
     bindingDescription.binding = 0;
     bindingDescription.stride = sizeof(Vertex);
     bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
 
     std::array<VkVertexInputAttributeDescription, 3> attributeDescriptions{};
     
     // 位置
     attributeDescriptions[0].binding = 0;
     attributeDescriptions[0].location = 0;
     attributeDescriptions[0].format = VK_FORMAT_R32G32B32_SFLOAT;
     attributeDescriptions[0].offset = offsetof(Vertex, pos);
     
     // 颜色
     attributeDescriptions[1].binding = 0;
     attributeDescriptions[1].location = 1;
     attributeDescriptions[1].format = VK_FORMAT_R32G32B32A32_SFLOAT;
     attributeDescriptions[1].offset = offsetof(Vertex, color);
     
     // 法向量
     attributeDescriptions[2].binding = 0;
     attributeDescriptions[2].location = 2;
     attributeDescriptions[2].format = VK_FORMAT_R32G32B32_SFLOAT;
     attributeDescriptions[2].offset = offsetof(Vertex, normal);
 
     VkPipelineVertexInputStateCreateInfo vertexInputInfo{};
     vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
     vertexInputInfo.vertexBindingDescriptionCount = 1;
     vertexInputInfo.pVertexBindingDescriptions = &bindingDescription;
     vertexInputInfo.vertexAttributeDescriptionCount = static_cast<uint32_t>(attributeDescriptions.size());
     vertexInputInfo.pVertexAttributeDescriptions = attributeDescriptions.data();
 
     // 输入装配
     VkPipelineInputAssemblyStateCreateInfo inputAssembly{};
     inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
     inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
     inputAssembly.primitiveRestartEnable = VK_FALSE;
 
     // 视口状态
     VkViewport viewport{};
     viewport.x = 0.0f;
     viewport.y = 0.0f;
     viewport.width = (float) mSwapChainExtent.width;
     viewport.height = (float) mSwapChainExtent.height;
     viewport.minDepth = 0.0f;
     viewport.maxDepth = 1.0f;
 
     VkRect2D scissor{};
     scissor.offset = {0, 0};
     scissor.extent = mSwapChainExtent;
 
     VkPipelineViewportStateCreateInfo viewportState{};
     viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
     viewportState.viewportCount = 1;
     viewportState.pViewports = &viewport;
     viewportState.scissorCount = 1;
     viewportState.pScissors = &scissor;
 
     // 光栅化器
     VkPipelineRasterizationStateCreateInfo rasterizer{};
     rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
     rasterizer.depthClampEnable = VK_FALSE;
     rasterizer.rasterizerDiscardEnable = VK_FALSE;
     rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
     rasterizer.lineWidth = 1.0f;
     rasterizer.cullMode = VK_CULL_MODE_BACK_BIT;
     rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE;
     rasterizer.depthBiasEnable = VK_FALSE;
 
     // 多重采样
     VkPipelineMultisampleStateCreateInfo multisampling{};
     multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
     multisampling.sampleShadingEnable = VK_FALSE;
     multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
 
     // 颜色混合
     VkPipelineColorBlendAttachmentState colorBlendAttachment{};
     colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | 
                                          VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
     colorBlendAttachment.blendEnable = VK_FALSE;
 
     VkPipelineColorBlendStateCreateInfo colorBlending{};
     colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
     colorBlending.logicOpEnable = VK_FALSE;
     colorBlending.logicOp = VK_LOGIC_OP_COPY;
     colorBlending.attachmentCount = 1;
     colorBlending.pAttachments = &colorBlendAttachment;
 
     // 管线布局
     VkPipelineLayoutCreateInfo pipelineLayoutInfo{};
     pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
     pipelineLayoutInfo.setLayoutCount = 1;
     pipelineLayoutInfo.pSetLayouts = &mDescriptorSetLayout;
 
     VK_CHECK(vkCreatePipelineLayout(mDevice, &pipelineLayoutInfo, nullptr, &mPipelineLayout));
 
     // 创建图形管线
     VkGraphicsPipelineCreateInfo pipelineInfo{};
     pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
     pipelineInfo.stageCount = 2;
     pipelineInfo.pStages = shaderStages;
     pipelineInfo.pVertexInputState = &vertexInputInfo;
     pipelineInfo.pInputAssemblyState = &inputAssembly;
     pipelineInfo.pViewportState = &viewportState;
     pipelineInfo.pRasterizationState = &rasterizer;
     pipelineInfo.pMultisampleState = &multisampling;
     pipelineInfo.pColorBlendState = &colorBlending;
     pipelineInfo.layout = mPipelineLayout;
     pipelineInfo.renderPass = mRenderPass;
     pipelineInfo.subpass = 0;
     pipelineInfo.basePipelineHandle = VK_NULL_HANDLE;
 
     VK_CHECK(vkCreateGraphicsPipelines(mDevice, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &mGraphicsPipeline));
 
     // 清理着色器模块
     vkDestroyShaderModule(mDevice, fragShaderModule, nullptr);
     vkDestroyShaderModule(mDevice, vertShaderModule, nullptr);
 
     return 0;
 }
 
 int32_t Tetrahedron::CreateFramebuffers()
 {
     mSwapChainFramebuffers.resize(mSwapChainImageViews.size());
 
     for (size_t i = 0; i < mSwapChainImageViews.size(); i++) {
         VkImageView attachments[] = {
             mSwapChainImageViews[i]
         };
 
         VkFramebufferCreateInfo framebufferInfo{};
         framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
         framebufferInfo.renderPass = mRenderPass;
         framebufferInfo.attachmentCount = 1;
         framebufferInfo.pAttachments = attachments;
         framebufferInfo.width = mSwapChainExtent.width;
         framebufferInfo.height = mSwapChainExtent.height;
         framebufferInfo.layers = 1;
 
         VK_CHECK(vkCreateFramebuffer(mDevice, &framebufferInfo, nullptr, &mSwapChainFramebuffers[i]));
     }
 
     return 0;
 }
 
 int32_t Tetrahedron::CreateCommandPool()
 {
     QueueFamilyIndices queueFamilyIndices = FindQueueFamilies(mPhysicalDevice);
 
     VkCommandPoolCreateInfo poolInfo{};
     poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
     poolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
     poolInfo.queueFamilyIndex = queueFamilyIndices.graphicsFamily;
 
     VK_CHECK(vkCreateCommandPool(mDevice, &poolInfo, nullptr, &mCommandPool));
     return 0;
 }
 
 uint32_t Tetrahedron::FindMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties)
 {
     VkPhysicalDeviceMemoryProperties memProperties;
     vkGetPhysicalDeviceMemoryProperties(mPhysicalDevice, &memProperties);
 
     for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++) {
         if ((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties) {
             return i;
         }
     }
 
     LOGE("Failed to find suitable memory type");
     return UINT32_MAX;
 }
 
 int32_t Tetrahedron::CreateVertexBuffer()
 {
     VkDeviceSize bufferSize = sizeof(vertices[0]) * vertices.size();
 
     VkBufferCreateInfo bufferInfo{};
     bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
     bufferInfo.size = bufferSize;
     bufferInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
     bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
 
     VK_CHECK(vkCreateBuffer(mDevice, &bufferInfo, nullptr, &mVertexBuffer));
 
     VkMemoryRequirements memRequirements;
     vkGetBufferMemoryRequirements(mDevice, mVertexBuffer, &memRequirements);
 
     VkMemoryAllocateInfo allocInfo{};
     allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
     allocInfo.allocationSize = memRequirements.size;
     allocInfo.memoryTypeIndex = FindMemoryType(memRequirements.memoryTypeBits, 
                                               VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
 
     VK_CHECK(vkAllocateMemory(mDevice, &allocInfo, nullptr, &mVertexBufferMemory));
     VK_CHECK(vkBindBufferMemory(mDevice, mVertexBuffer, mVertexBufferMemory, 0));
 
     void* data;
     vkMapMemory(mDevice, mVertexBufferMemory, 0, bufferSize, 0, &data);
     memcpy(data, vertices.data(), (size_t) bufferSize);
     vkUnmapMemory(mDevice, mVertexBufferMemory);
 
     return 0;
 }
 
 int32_t Tetrahedron::CreateUniformBuffers()
 {
     VkDeviceSize bufferSize = sizeof(UniformBufferObject);
 
     mUniformBuffers.resize(MAX_FRAMES_IN_FLIGHT);
     mUniformBuffersMemory.resize(MAX_FRAMES_IN_FLIGHT);
     mUniformBuffersMapped.resize(MAX_FRAMES_IN_FLIGHT);
 
     for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
         VkBufferCreateInfo bufferInfo{};
         bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
         bufferInfo.size = bufferSize;
         bufferInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
         bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
 
         VK_CHECK(vkCreateBuffer(mDevice, &bufferInfo, nullptr, &mUniformBuffers[i]));
 
         VkMemoryRequirements memRequirements;
         vkGetBufferMemoryRequirements(mDevice, mUniformBuffers[i], &memRequirements);
 
         VkMemoryAllocateInfo allocInfo{};
         allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
         allocInfo.allocationSize = memRequirements.size;
         allocInfo.memoryTypeIndex = FindMemoryType(memRequirements.memoryTypeBits,
                                                   VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
 
         VK_CHECK(vkAllocateMemory(mDevice, &allocInfo, nullptr, &mUniformBuffersMemory[i]));
         VK_CHECK(vkBindBufferMemory(mDevice, mUniformBuffers[i], mUniformBuffersMemory[i], 0));
         VK_CHECK(vkMapMemory(mDevice, mUniformBuffersMemory[i], 0, bufferSize, 0, &mUniformBuffersMapped[i]));
     }
 
     return 0;
 }
 
 int32_t Tetrahedron::CreateDescriptorPool()
 {
     VkDescriptorPoolSize poolSize{};
     poolSize.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
     poolSize.descriptorCount = static_cast<uint32_t>(MAX_FRAMES_IN_FLIGHT);
 
     VkDescriptorPoolCreateInfo poolInfo{};
     poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
     poolInfo.poolSizeCount = 1;
     poolInfo.pPoolSizes = &poolSize;
     poolInfo.maxSets = static_cast<uint32_t>(MAX_FRAMES_IN_FLIGHT);
 
     VK_CHECK(vkCreateDescriptorPool(mDevice, &poolInfo, nullptr, &mDescriptorPool));
     return 0;
 }
 
 int32_t Tetrahedron::CreateDescriptorSets()
 {
     std::vector<VkDescriptorSetLayout> layouts(MAX_FRAMES_IN_FLIGHT, mDescriptorSetLayout);
     VkDescriptorSetAllocateInfo allocInfo{};
     allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
     allocInfo.descriptorPool = mDescriptorPool;
     allocInfo.descriptorSetCount = static_cast<uint32_t>(MAX_FRAMES_IN_FLIGHT);
     allocInfo.pSetLayouts = layouts.data();
 
     mDescriptorSets.resize(MAX_FRAMES_IN_FLIGHT);
     VK_CHECK(vkAllocateDescriptorSets(mDevice, &allocInfo, mDescriptorSets.data()));
 
     for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
         VkDescriptorBufferInfo bufferInfo{};
         bufferInfo.buffer = mUniformBuffers[i];
         bufferInfo.offset = 0;
         bufferInfo.range = sizeof(UniformBufferObject);
 
         VkWriteDescriptorSet descriptorWrite{};
         descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
         descriptorWrite.dstSet = mDescriptorSets[i];
         descriptorWrite.dstBinding = 0;
         descriptorWrite.dstArrayElement = 0;
         descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
         descriptorWrite.descriptorCount = 1;
         descriptorWrite.pBufferInfo = &bufferInfo;
 
         vkUpdateDescriptorSets(mDevice, 1, &descriptorWrite, 0, nullptr);
     }
 
     return 0;
 }
 
 int32_t Tetrahedron::CreateCommandBuffers()
 {
     mCommandBuffers.resize(MAX_FRAMES_IN_FLIGHT);
 
     VkCommandBufferAllocateInfo allocInfo{};
     allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
     allocInfo.commandPool = mCommandPool;
     allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
     allocInfo.commandBufferCount = (uint32_t) mCommandBuffers.size();
 
     VK_CHECK(vkAllocateCommandBuffers(mDevice, &allocInfo, mCommandBuffers.data()));
     return 0;
 }
 
 int32_t Tetrahedron::CreateSyncObjects()
 {
     mImageAvailableSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
     mRenderFinishedSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
     mInFlightFences.resize(MAX_FRAMES_IN_FLIGHT);
 
     VkSemaphoreCreateInfo semaphoreInfo{};
     semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
 
     VkFenceCreateInfo fenceInfo{};
     fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
     fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
 
     for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
         VK_CHECK(vkCreateSemaphore(mDevice, &semaphoreInfo, nullptr, &mImageAvailableSemaphores[i]));
         VK_CHECK(vkCreateSemaphore(mDevice, &semaphoreInfo, nullptr, &mRenderFinishedSemaphores[i]));
         VK_CHECK(vkCreateFence(mDevice, &fenceInfo, nullptr, &mInFlightFences[i]));
     }
 
     return 0;
 }
 
 void Tetrahedron::UpdateUniformBuffer(uint32_t currentImage, float angleX, float angleY)
 {
     const float pi = 3.141592f;
 
     UniformBufferObject ubo{};
     
     // Y轴旋转矩阵
     float radianY = (angleY * pi) / 180.0f;
     float cosY = cosf(radianY);
     float sinY = sinf(radianY);
     float myArr[] = {
         cosY, 0, -sinY, 0,
         0, 1, 0, 0,
         sinY, 0, cosY, 0,
         0, 0, 0, 1
     };
     memcpy(ubo.my, myArr, sizeof(myArr));
 
     // X轴旋转矩阵
     float radianX = (angleX * pi) / 180.0f;
     float cosX = cosf(radianX);
     float sinX = sinf(radianX);
     float mxArr[] = {
         1, 0, 0, 0, 
         0, cosX, -sinX, 0, 
         0, sinX, cosX, 0, 
         0, 0, 0, 1
     };
     memcpy(ubo.mx, mxArr, sizeof(mxArr));
 
     // 光照参数
     ubo.lightColor[0] = 1.0f;
     ubo.lightColor[1] = 1.0f;
     ubo.lightColor[2] = 1.0f;
     
     float x = 2.0f / sqrt(15);
     float y = 2.0f / sqrt(15);
     float z = 3.0f / sqrt(15);
     ubo.lightDirection[0] = x;
     ubo.lightDirection[1] = -y;
     ubo.lightDirection[2] = z;
 
     memcpy(mUniformBuffersMapped[currentImage], &ubo, sizeof(ubo));
 }
 
 void Tetrahedron::RecordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex)
 {
     VkCommandBufferBeginInfo beginInfo{};
     beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
 
     VK_CHECK(vkBeginCommandBuffer(commandBuffer, &beginInfo));
 
     VkRenderPassBeginInfo renderPassInfo{};
     renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
     renderPassInfo.renderPass = mRenderPass;
     renderPassInfo.framebuffer = mSwapChainFramebuffers[imageIndex];
     renderPassInfo.renderArea.offset = {0, 0};
     renderPassInfo.renderArea.extent = mSwapChainExtent;
 
     VkClearValue clearColor = {{{1.0f, 1.0f, 1.0f, 1.0f}}};
     renderPassInfo.clearValueCount = 1;
     renderPassInfo.pClearValues = &clearColor;
 
     vkCmdBeginRenderPass(commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
 
     vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, mGraphicsPipeline);
 
     VkBuffer vertexBuffers[] = {mVertexBuffer};
     VkDeviceSize offsets[] = {0};
     vkCmdBindVertexBuffers(commandBuffer, 0, 1, vertexBuffers, offsets);
 
     vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, mPipelineLayout, 0, 1, 
                            &mDescriptorSets[mCurrentFrame], 0, nullptr);
 
     vkCmdDraw(commandBuffer, static_cast<uint32_t>(vertices.size()), 1, 0, 0);
 
     vkCmdEndRenderPass(commandBuffer);
 
     VK_CHECK(vkEndCommandBuffer(commandBuffer));
 }
 
 void Tetrahedron::Update(float angleXOffset, float angleYOffset)
 {
    if (!mVulkanInitialized || mDevice == VK_NULL_HANDLE) {
        return; // 静默返回，避免调用未初始化的Vulkan函数
    }

     angleX = angleXOffset;
     angleY = angleYOffset;
 
     vkWaitForFences(mDevice, 1, &mInFlightFences[mCurrentFrame], VK_TRUE, UINT64_MAX);
 
     uint32_t imageIndex;
     VkResult result = vkAcquireNextImageKHR(mDevice, mSwapChain, UINT64_MAX, 
                                            mImageAvailableSemaphores[mCurrentFrame], 
                                            VK_NULL_HANDLE, &imageIndex);
 
     if (result == VK_ERROR_OUT_OF_DATE_KHR) {
         reSizeWindow(m_width, m_height);
         return;
     } else if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) {
         LOGE("Failed to acquire swap chain image");
         return;
     }
 
     vkResetFences(mDevice, 1, &mInFlightFences[mCurrentFrame]);
 
     vkResetCommandBuffer(mCommandBuffers[mCurrentFrame], 0);
     RecordCommandBuffer(mCommandBuffers[mCurrentFrame], imageIndex);
 
     UpdateUniformBuffer(mCurrentFrame, angleX, angleY);
 
     VkSubmitInfo submitInfo{};
     submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
 
     VkSemaphore waitSemaphores[] = {mImageAvailableSemaphores[mCurrentFrame]};
     VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
     submitInfo.waitSemaphoreCount = 1;
     submitInfo.pWaitSemaphores = waitSemaphores;
     submitInfo.pWaitDstStageMask = waitStages;
 
     submitInfo.commandBufferCount = 1;
     submitInfo.pCommandBuffers = &mCommandBuffers[mCurrentFrame];
 
     VkSemaphore signalSemaphores[] = {mRenderFinishedSemaphores[mCurrentFrame]};
     submitInfo.signalSemaphoreCount = 1;
     submitInfo.pSignalSemaphores = signalSemaphores;
 
     VK_CHECK(vkQueueSubmit(mGraphicsQueue, 1, &submitInfo, mInFlightFences[mCurrentFrame]));
 
     VkPresentInfoKHR presentInfo{};
     presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
 
     presentInfo.waitSemaphoreCount = 1;
     presentInfo.pWaitSemaphores = signalSemaphores;
 
     VkSwapchainKHR swapChains[] = {mSwapChain};
     presentInfo.swapchainCount = 1;
     presentInfo.pSwapchains = swapChains;
 
     presentInfo.pImageIndices = &imageIndex;
 
     result = vkQueuePresentKHR(mPresentQueue, &presentInfo);
 
     if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR) {
         reSizeWindow(m_width, m_height);
     } else if (result != VK_SUCCESS) {
         LOGE("Failed to present swap chain image");
     }
 
     mCurrentFrame = (mCurrentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
 }
 
 void Tetrahedron::reSizeWindow(int32_t width, int32_t height)
 {
     if ((0 >= width) || (0 >= height)) {
         LOGE("Tetrahedron::reSizeWindow: param error.");
         return;
     }

     if (!mVulkanInitialized || mDevice == VK_NULL_HANDLE) {
        LOGI("Vulkan not initialized, skipping resize.");
        return;
    }
     
     m_width = width;
     m_height = height;
     m_widthPercent = FIFTY_PERCENT * m_height / m_width;
     
     vkDeviceWaitIdle(mDevice);
     
     CleanupSwapChain();
     CreateSwapChain();
     CreateImageViews();
     CreateFramebuffers();
     
     LOGI("Window resized to %{public}d x %{public}d", width, height);
 }
 
 float Tetrahedron::GetAngleX()
 {
     return angleX;
 }
 
 float Tetrahedron::GetAngleY()
 {
     return angleY;
 }
 
 void Tetrahedron::CleanupSwapChain()
 {
     for (auto framebuffer : mSwapChainFramebuffers) {
         vkDestroyFramebuffer(mDevice, framebuffer, nullptr);
     }
 
     for (auto imageView : mSwapChainImageViews) {
         vkDestroyImageView(mDevice, imageView, nullptr);
     }
 
     vkDestroySwapchainKHR(mDevice, mSwapChain, nullptr);
 }
 
 int32_t Tetrahedron::Quit(void)
 {

    LOGI("=== Tetrahedron::Quit START ===");
    
    // 添加状态检查 - 防止在未初始化时调用cleanup
    if (!mVulkanInitialized || mDevice == VK_NULL_HANDLE) {
        LOGI("Vulkan was not initialized, skipping cleanup.");
        return 0;
    }

     vkDeviceWaitIdle(mDevice);

 
     CleanupSwapChain();
 
     for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
         vkDestroyBuffer(mDevice, mUniformBuffers[i], nullptr);
         vkFreeMemory(mDevice, mUniformBuffersMemory[i], nullptr);
     }
 
     vkDestroyDescriptorPool(mDevice, mDescriptorPool, nullptr);
 
     vkDestroyBuffer(mDevice, mVertexBuffer, nullptr);
     vkFreeMemory(mDevice, mVertexBufferMemory, nullptr);
 
     for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
         vkDestroySemaphore(mDevice, mRenderFinishedSemaphores[i], nullptr);
         vkDestroySemaphore(mDevice, mImageAvailableSemaphores[i], nullptr);
         vkDestroyFence(mDevice, mInFlightFences[i], nullptr);
     }
 
     vkDestroyCommandPool(mDevice, mCommandPool, nullptr);
 
     vkDestroyPipeline(mDevice, mGraphicsPipeline, nullptr);
     vkDestroyPipelineLayout(mDevice, mPipelineLayout, nullptr);
 
     vkDestroyDescriptorSetLayout(mDevice, mDescriptorSetLayout, nullptr);
 
     vkDestroyRenderPass(mDevice, mRenderPass, nullptr);
 
     vkDestroyDevice(mDevice, nullptr);
 
     vkDestroySurfaceKHR(mInstance, mSurface, nullptr);
     vkDestroyInstance(mInstance, nullptr);
 
     mShaderLoader.cleanup();
 
     LOGI("Vulkan Quit success.");
     return 0;
 }